//
//  KSServerClock.m
//  钰家家
//
//  Created by 孔 on 2023/10/19.
//

#import "KSServerClock.h"
#import "KSMacro.h"
@interface KSServerClock ()
@property (strong, nonatomic) NSDate* startTime;
@property (assign, nonatomic) NSInteger second;
@property (strong, nonatomic) NSTimer* timer;
@property (nonatomic, strong) NSMutableDictionary<NSString*,KSServerClockSecondClock>* lisenters;
@end

@implementation KSServerClock
+ (instancetype)serverTime{
    static KSServerClock* _clock = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _clock = [[super allocWithZone:NULL] init];
        [_clock _init];
        
    });
    return _clock;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone{
    return [self serverTime];
}

- (id)copyWithZone:(NSZone *)zone{
    return [self.class serverTime];
}

- (id)mutableCopyWithZone:(NSZone *)zone{
    return [self.class serverTime];
}

- (void)_init{
    self.second = 0;
    self.startTime = [NSDate new];
    self.lisenters = [NSMutableDictionary dictionary];
    [self performSelectorInBackground:@selector(run) withObject:nil];
}

- (void)run{
    @Weak(self);
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0
                                    repeats:YES
                                      block:^(NSTimer * _Nonnull timer) {
        selfWeak.second ++;
        [selfWeak.lisenters.allValues enumerateObjectsUsingBlock:^(KSServerClockSecondClock obj, NSUInteger idx, BOOL * stop) {
            !obj?:obj([selfWeak.startTime dateByAddingTimeInterval:selfWeak.second]);
        }];
    }];
    [[NSRunLoop currentRunLoop] run];
}

- (void)dealloc{
    if([self.timer isValid]){
        [self.timer invalidate];
        self.timer = nil;
    }
}

+ (void)resetTime:(NSDate *)time{
    KSServerClock.serverTime.second = 0;
    KSServerClock.serverTime.startTime = time;
}

+ (NSDate *)currentTime{
    NSDate* startTime = KSServerClock.serverTime.startTime;
    NSInteger second = KSServerClock.serverTime.second;
    return [startTime dateByAddingTimeInterval:second];
}

+ (void)addSecondClock:(KSServerClockSecondClock)lisenter key:(NSString*)key{
    KSServerClock* clock = KSServerClock.serverTime;
    [self removeSecondClock:key];
    [clock.lisenters setObject:lisenter forKey:key];
}

+ (void)removeSecondClock:(NSString *)key{
    KSServerClock* clock = KSServerClock.serverTime;
    if([clock.lisenters.allKeys containsObject:key]){
        [clock.lisenters removeObjectForKey:key];
    }
}
@end
